//
//  ViewController.m
//  27-Block
//
//  Created by dllo on 16/8/19.
//  Copyright © 2016年 DM.C. All rights reserved.
//

#import "ViewController.h"
#import "SecondViewController.h"
@interface ViewController ()
@property (retain, nonatomic) IBOutlet UILabel *textLabel;

// Block写在属性中
@property (nonatomic, copy) void (^xxxBlock)();
// bolok写在方法中
- (void)handleData:(void (^)(void))handleData;
@end

@implementation ViewController
- (void)dealloc {
    Block_release(_xxxBlock);
    [_textLabel release];
    [super dealloc];
}
- (void)handleData:(void (^)(void))handleData {
    [[NSURLSession sharedSession]dataTaskWithURL:[NSURL URLWithString:@""] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        handleData();
        
        }];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // 1.什么是Block? 它是消息传递机制之一
    // Block与函数相似, 有固定功能的代码段
    // 2.Block基本语法
    // 下面的代码相当于 int block
    //  1> block的声明, 类型 void(^)(void) 变量名block
    // 返回值类型:(^Block的名)(参数列表)
    void (^block)(void);
    //  2> block的赋值
    //  block变量 = ^(参数列表) {固定的代码段};
    block = ^(void) {
    };
    // 3.Block的几种形式
    // 有参有返回
    int (^sum)(int, int) = ^(int a, int b) {
        return  a + b;
        
    };
    // 无参无返回
    void (^block1)(void) = ^(void) {
        
    };
    // 无参无返回第二种方式(简化版)
    void(^block3)() = ^ {
        
    };
    // 有参无返回
    void (^preintNumber)(int number) = ^(int number){
        
    };
    // 无参有返回
    NSString * (^returnString)() = ^{
        
        return @"haha";
    };
    // 系统提供了代码段可以直接使用, inlineBlcok
//    <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
//        <#statements#>
//    };
    
    // 4.Block的调用
    sum(10, 10);
    preintNumber(120);
    block1();
    block3();
    NSLog(@"%@", returnString);
    // 5.系统中的block
    //  1> 模态 completion:(void (^ __nullable)(void))completion
//    [self presentViewController:[[UIViewController alloc] init] animated:YES completion:<#^(void)completion#>
    
    //  2> GCD (^dispatch_block_t block)(void)
//  dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
    //  3> 网络请求
    //  ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
    
//    [NSURLSession sharedSession] dataTaskWithRequest:<#(nonnull NSURLRequest *)#> completionHandler:<#^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)completionHandler#>
    
    // 6.Block写在属性和方法上
    // 属性block修饰符, 使用copy
    self.xxxBlock = block1;
    self.xxxBlock();
    // 带block的方法的调用
    [self handleData:^{
        self.xxxBlock = block1;
    }];
    // 7.Block修饰符
    // __block __weak __strong
    //  1> __block 在ARC下和MRC下有区别
    //  ARC和MRC都可以执行下面的操作
    //  但是ARC下不能避免循环引用问题
    //  MRC下可以
    //  可以在block内部修改外部变量
    //
    int __block a = 0;
    __block int b = 0;
    void (^blockTest)() = ^{
        a = 100;
        b = 10;
    };
    blockTest();
    
    //  2> __weak 弱引用 修饰Block外的变量
    //   只能在ARC下使用, 避免Block的循环引用
    
    //  3> __strong 强引用
    
}
- (IBAction)pushNextViewContrloller:(id)sender {
    SecondViewController  *second = [SecondViewController new];
    // 值传递, 需要实现Block
    // 下面一行代码就是告诉Block, 该指针弱引用(ARC下), 该指针为Block()
    SecondViewController * __block weakSecond = second;
    second.passTitle = ^(NSString *title) {
        // Block会对其内部的所有对象进行强引用
        self.textLabel.text = title;
        weakSecond.view.backgroundColor = [UIColor cyanColor];
    };
    [self.navigationController pushViewController:second animated:YES];
    [second release];


}




















- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
